/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package test_gui;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.text.*;
import com.jcraft.jsch.*;
import java.awt.*;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import javax.swing.border.*;

/**
 *
 * @author thleontev
 */

public class FMain extends JFrame {

    /**
     * @param args the command line arguments
     */
    private JInternalFrame jInternalFrame1, jInternalFrame2;
    private JDesktopPane desktopPane;
    private JFileChooser fileChooser;
    private JTextPane jTextPaneFile, jTextPaneTerm, jTextPaneCMD;
    private DefaultStyledDocument doc;
    private Style normal;
    private ByteArrayOutputStream myout;
    private ByteArrayInputStream myin;
    private StringWriter  mywr;
    private StringReader myrd;
    private Channel channel;
    private Session session;
    private JSch jsch;
    private InputStream in;
    private OutputStream out;
    private String strCMD;
    private String[] lines; 
    
    FMain(){
        super("F4!");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        
        desktopPane = new JDesktopPane(); 
       
        // главное меню
        JMenuBar menuBar = new JMenuBar();
        
        JMenu fileMenu = new JMenu();
        fileMenu.setText("Файл");
        
        JMenu SettingMenu = new JMenu();
        SettingMenu.setText("Настройки");
        
        JMenu HelpMenu = new JMenu();
        HelpMenu.setText("Помощь");
        
        JMenuItem AboutMenuItem = new JMenuItem();
        AboutMenuItem.setText("О программе");
        
        JMenuItem NewSessionMenuItem = new JMenuItem();
        NewSessionMenuItem.setText("Новое подключение ");
        
        JMenuItem OpenMenuItem = new JMenuItem();
        OpenMenuItem.setText("Открыть");
        
        JMenuItem SaveMenuItem = new JMenuItem();
        SaveMenuItem.setText("Сохранить");
       
        JMenuItem SaveAsMenuItem = new JMenuItem();
        SaveAsMenuItem.setText("Сохранить как ..");
        
        JMenuItem ExitAsMenuItem = new JMenuItem();
        ExitAsMenuItem.setText("Выход");
        
        fileMenu.add(NewSessionMenuItem);
        fileMenu.addSeparator();
        fileMenu.add(OpenMenuItem);
        fileMenu.add(SaveMenuItem);  SaveMenuItem.setEnabled(false);  // пока отключим, с сохранением заморочки
        fileMenu.add(SaveAsMenuItem) ;SaveAsMenuItem.setEnabled(false);
        fileMenu.addSeparator();
        fileMenu.add(ExitAsMenuItem);
        
        HelpMenu.add(AboutMenuItem);
        
        menuBar.add(fileMenu);
        menuBar.add(SettingMenu); SettingMenu.setEnabled(false);
        menuBar.add(HelpMenu);
        setJMenuBar(menuBar);
        
      
        setContentPane(desktopPane);
        
        NewSessionMenuItem.addActionListener(new MNewSessionActionListener());
        OpenMenuItem.addActionListener(new MOpenActionListener());
        ExitAsMenuItem.addActionListener(new MExitActionListener());
        AboutMenuItem.addActionListener (new MAboutMenuItemActionListener());
        
        setLocation(50,50);
        setSize(800, 600); 
        /*
        JPanel statusPanel = new JPanel();
        statusPanel.setPreferredSize(new Dimension(getWidth(), 16));
        statusPanel.setBorder(new BevelBorder(BevelBorder.LOWERED));
        statusPanel.setLayout(new BoxLayout(statusPanel, BoxLayout.X_AXIS));
        JLabel statusLabel = new JLabel("");
        statusLabel.setHorizontalAlignment(SwingConstants.LEFT);
        statusPanel.add(statusLabel);
        
        JProgressBar progressBar = new JProgressBar();
        progressBar.setStringPainted(true);
        progressBar.setMinimum(0);
        progressBar.setMaximum(100);
        progressBar.setValue(30);
        progressBar.setSize(10, 16);
        statusPanel.add(progressBar);
                
        statusPanel.setVisible(true);
        getContentPane().add(statusPanel, BorderLayout.SOUTH);*/
       
        setVisible(true);

    }

    private static class MExitActionListener implements ActionListener {
            public void actionPerformed(ActionEvent e) {
            System.exit(0);
        }
    }

    private static class MAboutMenuItemActionListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            FAbout formhelp=new FAbout();
            formhelp.setLocation(50,50);
            formhelp.setVisible(true);
        }
  
    }
    
    class MNewSessionActionListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
        String host="none";
        
        
        // фрейм для SIU
        jInternalFrame1 = new JInternalFrame();
        jInternalFrame1.setClosable(true);
        jInternalFrame1.setMaximizable(true);
        jInternalFrame1.setResizable(true);
        jInternalFrame1.setSize(400, 400);
        
        // текстовые поля
        jTextPaneTerm = new JTextPane();
        jTextPaneTerm.setEditable(false);
        jTextPaneCMD = new JTextPane();  
   
        JScrollPane jScrollPaneTerm = new JScrollPane(jTextPaneTerm);
        JSplitPane jSplitPane1 = new JSplitPane(JSplitPane.VERTICAL_SPLIT,jScrollPaneTerm, jTextPaneCMD);
        jSplitPane1.setResizeWeight(1.0);
        jSplitPane1.setDividerLocation(jInternalFrame1.getSize().height-100);
        
        jInternalFrame1.setVisible(true);

        jInternalFrame1.add(jSplitPane1);
        desktopPane.add(jInternalFrame1);

        // SSH!
        try {
            jsch=new JSch();
            
            host=JOptionPane.showInputDialog("Enter username@hostname","thleontev@sdf.org"); 
            String user=host.substring(0, host.indexOf('@'));
            host=host.substring(host.indexOf('@')+1);
 
            session=jsch.getSession(user, host, 22);
 
            String passwd = JOptionPane.showInputDialog("Enter password","cxzdsaewq");
            session.setPassword(passwd);
            
            UserInfo ui = new MyUserInfo(){
                public void showMessage(String message){
                    JOptionPane.showMessageDialog(null, message);
                }
                public boolean promptYesNo(String message){
                    Object[] options={ "yes", "no" };
                    int foo=JOptionPane.showOptionDialog(null, 
                                               message,
                                               "Warning", 
                                               JOptionPane.DEFAULT_OPTION, 
                                               JOptionPane.WARNING_MESSAGE,
                                               null, options, options[0]);
                    return foo==0;
               }
            };
            
            session.setUserInfo(ui);
            //session.setConfig("StrictHostKeyChecking", "no");
            session.connect(30000);
            
            
            channel=session.openChannel("shell");
            ((ChannelShell)channel).setPtyType("vt100");
            
            channel.connect(30000);

            in=channel.getInputStream();
            out=channel.getOutputStream();
            
            if(channel.isClosed()){
                jInternalFrame1.setTitle("SIU: disconnected!");
            } else {
                jInternalFrame1.setTitle("SIU: connected to "+host);
            }
            
             /*  byte[] tmp=new byte[1024];
      while(true){
        while(in.available()>0){
          int i=in.read(tmp, 0, 1024);
          if(i<0)break;
          System.out.print(new String(tmp, 0, i));
        }
        if(channel.isClosed()){
          System.out.println("exit-status: "+channel.getExitStatus());
          break;
        }
        try{Thread.sleep(1000);}catch(Exception ee){}
      }
*/
        }
        catch(Exception ee){
              System.out.println(ee);
            }
        
        
        //String result = new String(myout.toByteArray());
        //jTextPaneTerm.setText(result);

        jTextPaneCMD.addKeyListener(new KeyListener() {

            public void keyTyped(KeyEvent e) { 
                if(e.getKeyChar()=='\n'){
                    try {
                        out.write((jTextPaneCMD.getText().substring(0, jTextPaneCMD.getText().length()-1)).getBytes());
                        out.flush();
                    } catch (IOException ex) {
                        java.util.logging.Logger.getLogger(FMain.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    jTextPaneCMD.setText(""); 

                } else {
                    if(e.getKeyChar()=='\b'){ // пропускаем backspace отдельно для тестов!
                        try {
                            out.write(e.getKeyChar());
                            out.flush();
                        } catch (IOException ex) {
                            java.util.logging.Logger.getLogger(FMain.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }
            }

            public void keyPressed(KeyEvent e) {
               // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.                
            }

            public void keyReleased(KeyEvent e) {
                //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }
        });
        
        
        Thread receivThread = new Thread() {
        String str;
        DataOutputStream os;
        
        public void run() { 
            byte[] tmp=new byte[2048];
            str="";
            try {
                os = new DataOutputStream(new FileOutputStream("test1.txt"));
            } catch (FileNotFoundException ex) {
                java.util.logging.Logger.getLogger(FMain.class.getName()).log(Level.SEVERE, null, ex);
            }
            
            while(true){
                try{Thread.sleep(1000);}catch(Exception ee){}
                try {
                    if (in.available()>0){
                        int i=in.read(tmp, 0, 2048);
                        if(i<0)break;
                        os.write(tmp, 0, 2048);
                        //os.flush();
                        // os.close();
                        str=new String(tmp, 0, i);
                    }
                } catch (IOException ex) {
                    java.util.logging.Logger.getLogger(FMain.class.getName()).log(Level.SEVERE, null, ex);
                }
                
               try {
                    SwingUtilities.invokeAndWait(new Runnable () {
                        public void run() {
                            if (str.length()>0) {
                                jTextPaneTerm.setText(jTextPaneTerm.getText()+str);
                                str="";
                            }
                        }
                    });
                } catch (InterruptedException ex) {
                    java.util.logging.Logger.getLogger(FMain.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InvocationTargetException ex) {
                    java.util.logging.Logger.getLogger(FMain.class.getName()).log(Level.SEVERE, null, ex);
                }
                //try{Thread.sleep(500);}catch(Exception ee){}
           }
        }
        };
        receivThread.start();

        } 
    }
    
    // обработка события открытие файла
    class MOpenActionListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
        
        jInternalFrame2 = new JInternalFrame();
        jInternalFrame2.setClosable(true);
        jInternalFrame2.setMaximizable(true);
        jInternalFrame2.setResizable(true);
        jInternalFrame2.setBounds(400, 0, 400, 400);
        
        jTextPaneFile = new JTextPane();
        JScrollPane jScrollPaneFile = new JScrollPane(jTextPaneFile);
        jInternalFrame2.add(jScrollPaneFile);
        
        // открытие файла
        fileChooser = new JFileChooser();
        int returnVal = fileChooser.showOpenDialog(FMain.this);
        File selectedFile = fileChooser.getSelectedFile();
        if(selectedFile != null)
        {
            readFile(selectedFile.getAbsolutePath());
         }
        jInternalFrame2.setTitle(selectedFile.getName());
        desktopPane.add(jInternalFrame2);
        jInternalFrame2.setVisible(true);
        
        // обработчик F4!!!
        jTextPaneFile.addKeyListener(new KeyListener() {
            FProgress fprogress;
            
            public void keyTyped(KeyEvent e) {
            }

            public void keyPressed(KeyEvent e) {
                 if(e.getKeyCode() == KeyEvent.VK_F4){
                 
                 lines=jTextPaneFile.getSelectedText().split("\\n");
                 fprogress=new FProgress();
                 fprogress.setLocation(100,100);
                 fprogress.setValue(0);
                 fprogress.setMaximum(lines.length-1);
                 fprogress.setMinimum(0);
                 fprogress.setVisible(true);
                 
                 Thread sendThread = new Thread() {
                 public void run() {   
                 for(int i = 0 ; i< lines.length; i++)  {  
                      try {
                        out.write((lines[i]+"\r\n").getBytes());
                        out.flush();
                        fprogress.setValue(i);
                        // пауза
                        try{Thread.sleep(500);}catch(Exception ee){}
                        
                      } catch (IOException ex) {
                        java.util.logging.Logger.getLogger(FMain.class.getName()).log(Level.SEVERE, null, ex);
                        }         
                    }
                 
                }

                 };
                sendThread.start();
              }
            }
            public void keyReleased(KeyEvent e) {  
            }
        });
    }

    private void readFile(String selectedFileName)
    {
        StyleContext sc = new StyleContext(); 
        doc = new DefaultStyledDocument( sc ) ; 
        normal = jTextPaneFile.addStyle("Normal", null);
        StyleConstants.setFontFamily(normal, "Verdana");
        StyleConstants.setFontSize(normal, 13);
        
        try
        {
            BufferedReader br = new BufferedReader(new FileReader(selectedFileName));
            StringBuffer sb = new StringBuffer();
            String line = br.readLine();
            
            while(line != null)
            {
                doc.insertString(doc.getLength(), line+'\n', normal);
                line = br.readLine();
            }  
            jTextPaneFile.setDocument(doc);
            br.close();
        }
     catch (Exception ex) {
        ex.printStackTrace();
       }
      }
    } 
    
    public static abstract class MyUserInfo
                          implements UserInfo, UIKeyboardInteractive{
    public String getPassword(){ return null; }
    public boolean promptYesNo(String str){ return false; }
    public String getPassphrase(){ return null; }
    public boolean promptPassphrase(String message){ return false; }
    public boolean promptPassword(String message){ return false; }
    public void showMessage(String message){ }
    public String[] promptKeyboardInteractive(String destination,
                                              String name,
                                              String instruction,
                                              String[] prompt,
                                              boolean[] echo){
      return null;
    }
  } 
    
    public static void main(String[] args) {
        // TODO code application logic here
        new FMain();
    }
}
